#include "LPC11xx.h"
#include "oled.h"
#include "spi.h"
#include "bitops.h"
#include "font.h"
#include <string.h>

#define COLN  128
#define PAGEN 8

// 4-wire SPI
void send_cmd(unsigned char cmd)
{
  //拉低片选引脚
  clrbit(LPC_GPIO2->DATA, 4);
  clrbit(LPC_GPIO2->DATA, 5); //发送命令
  spi0_send(cmd);
  setbit(LPC_GPIO2->DATA, 5);
  setbit(LPC_GPIO2->DATA, 4);
}

void send_data(unsigned char data)
{
  //拉低片选引脚
  clrbit(LPC_GPIO2->DATA, 4);
  setbit(LPC_GPIO2->DATA, 5); //发送数据
  spi0_send(data);
  setbit(LPC_GPIO2->DATA, 5);
  setbit(LPC_GPIO2->DATA, 4);
}

void set_addressing_mode(unsigned char mode)
{
  send_cmd(0x20);       // Set Memory Addressing Mode
  send_cmd(mode);       //   Default => 0x02
                        //     0x00 => Horizontal Addressing Mode
                        //     0x01 => Vertical Addressing Mode
                        //     0x02 => Page Addressing Mode
}

void set_column_address(unsigned char begin, unsigned char end)
{
  send_cmd(0x21);
  send_cmd(begin);
  send_cmd(end);
}

void set_page_address(unsigned char begin, unsigned char end)
{
  send_cmd(0x22);
  send_cmd(begin);
  send_cmd(end);
}

void set_start_line(unsigned char line)
{
  send_cmd(0x40 | line);  // Set Display Start Line
                       //   Default => 0x40 (0x00)
}

void set_contrast(unsigned char contrast)
{
  send_cmd(0x81);
  send_cmd(contrast);
}

void enable_charge_pump(void)
{
  send_cmd(0x8D);
  send_cmd(0x14);
}

void remap_segment(void)
{
  send_cmd(0xA1);
}

void remap_common(void)
{
  send_cmd(0xC8);
}

void set_display_on(void)
{
  send_cmd(0xAF);
}

void oled_clear(unsigned char pattern)
{
  int i;

  set_page_address(0, PAGEN - 1);
  set_column_address(0, COLN - 1);

  for(i = 0; i < PAGEN * COLN; i++)
  {
    send_data(pattern);
  }
}

void oled_init(uint8_t contrast)
{
  setbit(LPC_GPIO2->DIR, 5); //DC
  setbit(LPC_GPIO2->DIR, 4); //CS
  
  enable_charge_pump();
  remap_segment();
  remap_common();
  set_contrast(contrast);
  set_addressing_mode(0); //水平寻址
  oled_clear(0);
  set_display_on();
}

void oled_putchar(unsigned char page, unsigned char column, char c)
{
  int i;
  set_page_address(page, page + 1);
  set_column_address(column, column + 7);
  for (i = 0; i < 16; i++)
  {
    send_data(ascii[c - 32][i]);
  }
}

void oled_puts(unsigned char page, unsigned char column, char* s)
{
  unsigned int n = strlen(s);
  unsigned int i;
  for (i = 0; i < n; i++)
  {
    oled_putchar(page, column + 8 * i, s[i]);
  }
}

void oled_puthz(unsigned char page, unsigned char column, unsigned char* font)
{
  int i;
  set_page_address(page, page + 1);
  set_column_address(column, column + 15);
  for (i = 0; i < 32; i++)
  {
    send_data(font[i]);
  }
}

//显示图像
//page: 起始行（单位为页）
//column: 起始列
//image: 图像数组
//height: 图像高度（单位为页）
//width: 图像宽度
void oled_showimage(unsigned char page, unsigned char column, unsigned char* image, unsigned char height, unsigned char width)
{
  int i;
  set_page_address(page, page + height - 1);
  set_column_address(column, column + width - 1);
  for (i = 0; i < height*width; i++)
  {
    send_data(image[i]);
  }
}
